
package ext.opensource.netty.server.httpsocket;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.CharsetUtil;

public class HttpResourceHander extends SimpleChannelInboundHandler<FullHttpRequest> {
	private final BaseHttpResource httpResource;

	public HttpResourceHander(final BaseHttpResource httpResource) {
		this.httpResource = httpResource;
	}

	@Override
	protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpRequest req) throws Exception {

		final String uri = req.uri();
		final int index = uri.indexOf("?");
		String path = null;
		if (index == -1) {
			path = uri;
		} else {
			path = uri.substring(0, index);
		}

		if (httpResource != null) {
			final String resFileName = path;

			final ByteBuf res = httpResource.buildWebSocketRes(req, resFileName);
			if (null == res) {
				HttpResourceHander.sendHttpResponse(ctx, req,
						new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND));
				return;
			} else {
				HttpResourceHander.sendHttpResponse(ctx, req,
						new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, res));
			}
		}
	}

	private static void sendHttpResponse(final ChannelHandlerContext ctx, final FullHttpRequest req,
			final FullHttpResponse res) {
		// Generate an error page if response getStatus code is not OK (200).
		final int statusCode = res.status().code();
		if (statusCode != HttpResponseStatus.OK.code() && res.content().readableBytes() == 0) {
			final ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), CharsetUtil.UTF_8);
			res.content().writeBytes(buf);
			buf.release();
		}
		HttpUtil.setContentLength(res, res.content().readableBytes());

		// Send the response and close the connection if necessary.
		if (!HttpUtil.isKeepAlive(req) || statusCode != HttpResponseStatus.OK.code()) {
			res.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
			ctx.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE);
		} else {
			res.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
			ctx.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE);
		}
	}
}
